//
//  calculator.h
//  TestPrizeCaculator
//
//  Created by 苏宇靖 on 2018/7/5.
//  Copyright © 2018年 Zeeging Tech. All rights reserved.
//

#ifndef calculator_h
#define calculator_h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define MAX_GGTYPE          15+1  // 过关类型数量
#define MAX_SELECT          54+1  // 选项数量
#define MAX_PLAY             6+1  // 玩法数量
#define MAX_MATCH           15+1  // 场次数量
#define MAX_SPLIT            256  // 最大分割项
#define MAX_MALLOC          100*1024  // 每次最大申请内存数

#define ERR_UNPACK_PARAM       -1  // 参数错误
#define ERR_UNPACK_GGTYPE      -2  // 解包过关类型出错
#define ERR_UNKNOWN_GGTYPE     -3  // 未知的过关类型
#define ERR_UNPACK_CONTENT     -4  // 解包投注内容出错
#define ERR_UNPACK_MATCH       -5  // 解包赛事出错
#define ERR_UNPACK_SELECT      -6  // 解包选项出错
#define ERR_UNKNOWN_PLAY       -7  // 未知的玩法
#define ERR_MALLOC             -8  // 分配内存出错
#define ERR_ANALYSIS           -9  // 分析出错
#define ERR_LOTTERY           -10  // 错误的彩种
#define ERR_UNKNOWN_EXP       -99  // 未知异常

// 过关类型
typedef struct {
    char name[10];              // 名称
    int gg[MAX_MATCH];          // 过关类型
    int matchs;                 // 赛事数
    int matchs_min;             // 最小赛事数
    int bets;                   // 注数
} GGType;

// 选项
typedef struct {
    void    *match;         // 赛事指针，反指对应的赛事
    int     playid;         // 玩法ID
    double  odds;           // 赔率
    int     select;         // 选项
    double  home_score;     // 主队得分
    double  away_score;     // 客队得分
    double  extra_score;    // 让分
    int     ismax;          // 是否最大赔率选项 0-否 1是
    char    raw[50];        // 选项的原始内容 场次ID#玩法#选择#赔率
} Select;

// 场次
typedef struct{
    char    id[32];
    // 场次ID
    int     fixed;                              // 胆码 0否 1是
    Select  sel[MAX_SELECT];                    // 选项
    int     sel_size;                           // 选项数
    Select  *play[MAX_PLAY][MAX_SELECT];        // 按玩法分类选项
    int     play_size;                          // 玩法数量
    double  extra_score;                        // 让分
} Match;

// 方案
typedef struct {
    int     lot;                    // 彩种
    int     match_size;             // 场次数
    Match   match[MAX_MATCH];       // 场次
    int     fixed_size;             // 胆码数
    GGType  ggtype[MAX_GGTYPE];     // 过关类型集合
    int     ggtype_size;            // 过关类型数
    int     ismix;                  // 是否混投 0否 1是
    int     isdupl;                 // 是否可重复 0否 1是
} Project;

typedef struct {
    double  min;            // 最小奖金
    double  max;            // 最大奖金
    long    betcnt;         // 注数
    char    *betlist;       // 投注内容列表
} Bet;

typedef struct {
    Select *sel[MAX_PLAY];
    double odds;
    int size;
} OddsComb;

// 彩种
enum {
    LOT_JCZQ=46,     // 竞彩足球
    LOT_JCLQ=47,     // 竞彩篮球
    LOT_BJDC=9       // 北京单场
};

// 玩法
enum {
    // 竞彩足球
    JZ_SPF=0,       // 竞足胜平负 354
    JZ_RQSPF,       // 竞足让球胜平负 269
    JZ_BF,          // 竞足比分 271
    JZ_ZJQ,         // 竞足总进球 270
    JZ_BQC,         // 竞足半全场 272
    
    // 北单玩法
    BD_RQSPF,       // 北单让球胜平负 34
    BD_SFGG,        // 北单胜负过关 407
    BD_ZJQ,         // 北单总进球 40
    BD_SXDS,        // 北单上下单双 41
    BD_BF,          // 北单比分 42
    BD_BQC,         // 北单半全场 51
    
    // 竞篮玩法
    JL_SF,          // 竞篮胜负 274
    JL_RFSF,        // 竞篮让分胜负 275
    JL_SFC,         // 竞篮胜分差 276
    JL_DXF,         // 竞篮大小分 277
};

int split(char *str, char delim, char *res[MAX_SPLIT]);
void print_project();
int unpack(char *ggtype, char *content);
int unpack_ggtype(char *str);
int unpack_content(char *str);
int unpack_match(char *str);
int unpack_select(char *str);
int calc_max_odds_comb();
int check_compatible_jczq(int i, Select *select);
int check_compatible_jclq(int i, Select *select);
int calc_bet_dupl();
int calc_bet_dulp_1(int ggidx);
int calc_bet_dulp_2(int ggidx, Match *match[MAX_MATCH], int size);
int calc_bet_dulp_3(int gg, Select **play[MAX_MATCH], int size);
int calc_bet_dulp_4(Select **play[MAX_MATCH], int size);
int calc_bet();
int calc_bet_1(int gg);
int calc_bet_2(Match *match[MAX_MATCH], int size);
int add_bet(Select *sel[MAX_MATCH], int size);
int calc_bouns(Select *sel[MAX_MATCH], int size);

// 接口函数
// lot 彩种
// ggtype 过关类型 2*1;3*4;
// content 投注内容 场次ID|让球(分)|是否胆码(0或1)|玩法#选择#赔率/玩法#选择#赔率/...;场次ID|让球(分)....
// 竞彩足球 比方 999:0 胜其他 0:999负其他 999:999平其他
// 竞彩篮球胜分差
// 0-11 分别代表主队胜1-5到客队胜26+
// 竞彩篮球大小分
// +100大于100分 -100小于100分
// ismix 是否混投 0-否 1-是
// isdupl 是否可重复 0-否 1-是
// min 最小奖金
// max 最大奖金
// betcnt 注数
// betlist 投注列表 如果为空代表不需要返回列表，如果不为空代表在外部已经申请好内存块，这里需要由外部计算好内存块大小，避免内存溢出崩溃
//         场次ID#玩法#选择#赔率;场次ID#玩法#选择#赔率...|场次ID#玩法#选择#赔率;场次ID#玩法#选择#赔率...
// 返回值 >0 成功 <0 错误码
int api_calc_bet(int lot, char *ggtype, char *content, int ismix, int isdupl, double *min, double *max, long *betcnt, char *betlist);

#endif /* calculator_h */
